package com.ecoolex.ying.space.core.manager;

import com.ecoolex.framework.common.enums.ResultCode;
import com.ecoolex.framework.common.pojo.Page;
import com.ecoolex.framework.common.pojo.Pagination;
import com.ecoolex.framework.common.pojo.Sorting;
import com.ecoolex.framework.common.pojo.Sortings;
import com.ecoolex.framework.common.util.BizAssert;
import com.ecoolex.framework.common.util.Check;
import com.ecoolex.framework.common.util.RandomUtil;
import com.ecoolex.ying.space.core.dao.EstateProjectActivityCouponPackageDAO;
import com.ecoolex.ying.space.core.service.WeiXinPayService;
import com.ecoolex.ying.space.entity.EstateProjectActivityCoupon;
import com.ecoolex.ying.space.entity.EstateProjectActivityCouponOrder;
import com.ecoolex.ying.space.entity.EstateProjectActivityCouponPackage;
import com.ecoolex.ying.space.entity.EstateProjectActivityCouponPackage.Column;
import com.ecoolex.ying.space.entity.EstateProjectActivityCouponPackageExample;
import com.ecoolex.ying.space.entity.EstateProjectActivityCouponPackageExample.Criteria;
import com.ecoolex.ying.space.enums.EstateProjectActivityCouponPackageStatus;

import java.time.Instant;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class EstateProjectActivityCouponPackageManager {
	
    @Autowired
    private EstateProjectActivityCouponPackageDAO dao;
    
    @Autowired
    private EstateProjectActivityCouponManager couponManager;
    
    @Autowired
    private WeiXinPayService weiXinPayService;
    
    @Autowired
    private EstateProjectActivityCouponOrderManager orderManager;
    
    public void add(EstateProjectActivityCouponOrder order,String createUser) {
    	EstateProjectActivityCoupon coupon = couponManager.getEstateProjectActivityCoupon(order.getCouponId());
    	BizAssert.isTrue(Check.notNull(coupon),ResultCode.VERIFY.build(20), "代金券不存在");
    	for(int i = 0;i<order.getBuyNumber();i++) {
    		String code = code();
    		EstateProjectActivityCouponPackage couponPackage = new EstateProjectActivityCouponPackage();
    		couponPackage.setCouponId(coupon.getCouponId());
    		couponPackage.setCode(code);
    		couponPackage.setOrderId(order.getOrderId());
    		couponPackage.setStatus(EstateProjectActivityCouponPackageStatus.UNUSED.real());
    		couponPackage.setUserId(order.getUserId());
    		couponPackage.setEffectTime(coupon.getEffectTime());
    		couponPackage.setExpireTime(coupon.getExpireTime());
    		couponPackage.setDeleted(EstateProjectActivityCouponPackage.NOT_DELETED);
    		couponPackage.setCreateUser(createUser);
    		couponPackage.setCreateTime(Date.from(Instant.now()));
    		couponPackage.setUpdateUser(createUser);
    		couponPackage.setUpdateTime(Date.from(Instant.now()));
    		dao.insert(couponPackage);
    	}
    }
    
    private String code() {
    	String code = RandomUtil.randomInt(18);
		EstateProjectActivityCouponPackage old = getEstateProjectActivityCouponPackageByCode(code);
		if(Check.notNull(old)) {
			return code();
		}
		return code;
    }
    
    public void refund(EstateProjectActivityCouponOrder order,String updateUser) {
    	EstateProjectActivityCouponPackage couponPackage = getByOrderIdAndUserId(order.getOrderId(),order.getUserId());
    	BizAssert.isTrue(Check.notNull(couponPackage), "用户代金券不存在");
    	couponPackage.setStatus(EstateProjectActivityCouponPackageStatus.REFUND.real());
    	couponPackage.setRefundTime(Date.from(Instant.now()));
    	couponPackage.setUpdateUser(updateUser);
    	couponPackage.setUpdateTime(Date.from(Instant.now()));
    	dao.updateByPrimaryKeySelective(couponPackage, Column.status,Column.refundTime,Column.updateUser,Column.updateTime);
    }
    
    public void used(EstateProjectActivityCouponPackage couponPackage,String updateUser) {
    	couponPackage.setStatus(EstateProjectActivityCouponPackageStatus.USED.real());
    	couponPackage.setUseTime(Date.from(Instant.now()));
    	couponPackage.setUpdateUser(updateUser);
    	couponPackage.setUpdateTime(Date.from(Instant.now()));
    	dao.updateByPrimaryKeySelective(couponPackage, Column.status,Column.useTime,Column.updateUser,Column.updateTime);
    }
    
    public void expire(EstateProjectActivityCouponPackage couponPackage,String updateUser) {
    	couponPackage.setStatus(EstateProjectActivityCouponPackageStatus.EXPIRE.real());
    	couponPackage.setUpdateUser(updateUser);
    	couponPackage.setUpdateTime(Date.from(Instant.now()));
    	dao.updateByPrimaryKeySelective(couponPackage, Column.status,Column.updateUser,Column.updateTime);
    	//自动退款
    	EstateProjectActivityCouponOrder order = orderManager.getByOrderId(couponPackage.getOrderId());
    	weiXinPayService.weixinRefundApply(order, couponPackage, updateUser);
    }
    
    public EstateProjectActivityCouponPackage getByOrderIdAndUserId(Integer orderId,Integer userId) {
    	EstateProjectActivityCouponPackageExample example = new EstateProjectActivityCouponPackageExample();
		Criteria criteria = example.createCriteria();
		criteria.andOrderIdEqualTo(orderId).andUserIdEqualTo(userId).andDeletedEqualTo(EstateProjectActivityCouponPackage.NOT_DELETED);
		return dao.selectOneByExample(example);
    }
    
    public Pagination<EstateProjectActivityCouponPackage> couponPackageList(Integer status, Integer userId, Page page) {
		EstateProjectActivityCouponPackageExample example = new EstateProjectActivityCouponPackageExample();
		Criteria criteria = example.createCriteria();
		if(Check.notNull(status)) {
			criteria.andStatusEqualTo(status);
		}
		criteria.andUserIdEqualTo(userId).andDeletedEqualTo(EstateProjectActivityCouponPackage.NOT_DELETED);
		example.setOffset(page.getFirstIndex());
		example.setRows(page.getPageSize());
		example.orderBy(Column.createTime.desc());
    	return Pagination.create(page, 
    		dao.countByExample(example),
    		() -> dao.selectByExample(example));
	}
    
    public EstateProjectActivityCouponPackage getCouponPackage(Integer id) {
		return dao.selectByPrimaryKeyWithLogicalDelete(id, EstateProjectActivityCouponPackage.NOT_DELETED);
	}

	public Pagination<EstateProjectActivityCouponPackage> queryCouponPackage(String code, Integer status, Sorting[] sorts, Page page) {
		EstateProjectActivityCouponPackageExample example = new EstateProjectActivityCouponPackageExample();
		Criteria criteria = example.createCriteria();
		if(Check.notNull(status)) {
			criteria.andStatusEqualTo(status);
		}
		if(Check.notNullOrTrimEmpty(code)) {
			criteria.andCodeEqualTo(code);
		}
		criteria.andDeletedEqualTo(EstateProjectActivityCouponPackage.NOT_DELETED);
		example.setOffset(page.getFirstIndex());
		example.setRows(page.getPageSize());
		example.orderBy(Sortings.builder(sorts).verify(Column::valueOf).toSql());
    	return Pagination.create(page, 
    		dao.countByExample(example),
    		() -> dao.selectByExample(example));
	}

	public EstateProjectActivityCouponPackage couponPackage(Integer id,Integer userId) {
		EstateProjectActivityCouponPackageExample example = new EstateProjectActivityCouponPackageExample();
		Criteria criteria = example.createCriteria();
		criteria.andIdEqualTo(id).andUserIdEqualTo(userId).andDeletedEqualTo(EstateProjectActivityCouponPackage.NOT_DELETED);
		return dao.selectOneByExample(example);
	}
	
	public EstateProjectActivityCouponPackage getEstateProjectActivityCouponPackageByCode(String code, Integer userId) {
		EstateProjectActivityCouponPackageExample example = new EstateProjectActivityCouponPackageExample();
		Criteria criteria = example.createCriteria();
		criteria.andCodeEqualTo(code).andUserIdEqualTo(userId).andDeletedEqualTo(EstateProjectActivityCouponPackage.NOT_DELETED);
		return dao.selectOneByExample(example);
	}
	
	public EstateProjectActivityCouponPackage getEstateProjectActivityCouponPackageByCode(String code) {
		EstateProjectActivityCouponPackageExample example = new EstateProjectActivityCouponPackageExample();
		Criteria criteria = example.createCriteria();
		criteria.andCodeEqualTo(code).andDeletedEqualTo(EstateProjectActivityCouponPackage.NOT_DELETED);
		return dao.selectOneByExample(example);
	}
	
	public List<EstateProjectActivityCouponPackage> listByExpireTime(Date expireTime){
		EstateProjectActivityCouponPackageExample example = new EstateProjectActivityCouponPackageExample();
		Criteria criteria = example.createCriteria();
		criteria.andExpireTimeLessThan(expireTime).andStatusEqualTo(EstateProjectActivityCouponPackageStatus.UNUSED.real());
		return dao.selectByExample(example);
	}
	
	public EstateProjectActivityCoupon getCoupon(String code) {
		EstateProjectActivityCouponPackage couponPackage = getEstateProjectActivityCouponPackageByCode(code);
		return couponManager.getEstateProjectActivityCoupon(couponPackage.getCouponId());
	}
}